/*
 * @Author       : wfl
 * @LastEditors  : wfl
 * @description  :
 * @updateInfo   :
 * @Date         : 2022-11-07 17:26:38
 * @LastEditTime : 2023-08-02 09:33:15
 */
import { isRef, watch } from 'vue'

export const useRoles = (roleData: unknown, emit: any) => {
  const handChanging = ref(false)
  if (!isRef(roleData))
    throw new TypeError('useRoleHook: roleData must be an Ref')

  const deepSetList = (data: any[]) => {
    let list = [...data]
    data.forEach((item: { children: any; __children: any; }) => {
      if (item.children || item.__children)
        list = [...list, ...deepSetList(item.children || item.__children)]
    })
    return list
  }

  // hooks监听Ref数据变化
  watch(roleData, newVal => {
    roleData = newVal
  })

  // 遍历赋值
  const deepMap = (data: any[], checked: any) => {
    data.forEach((item: { checked: any; indeterminate: boolean; children: any; __children: any; }) => {
      item.checked = checked
      item.indeterminate = false
      if (item.children || item.__children)
        deepMap(item.children || item.__children, checked)
    })
  }

  // 向上依次寻找父级
  const findParent = <T>(data: any, child: { parentId: any; }): T | any => {
    for (const item of data) {
      if (item.id === child.parentId) {
        return item
      }
      else if (item.children) {
        const self = findParent(item.children, child)
        if (self)
          return self
      }
    }
  }

  const deepMapParent = async (data: any, checked: any) => {
    const parent = await findParent(roleData, data)
    if (parent) {
      const children = parent?.children || parent?.__children
      const allChecked = children.every((item: { checked: any; }) => item.checked)
      if (allChecked) {
        parent.checked = true
        parent.indeterminate = false
        deepMapParent(parent, checked)
      }
      else {
        parent.checked = false
        const someChecked = children.some((item: { checked: any; }) => item.checked)
        if (someChecked) {
          parent.indeterminate = true
        }
        else {
          const someIndete = children.some((item: { indeterminate: any; }) => item.indeterminate)
          parent.indeterminate = someIndete
        }
        deepMapParent(parent, checked)
      }
    }
  }

  const handChangeCheck = (item: { checked: any; indeterminate?: any; children?: any; __children?: any; }) => {
    const { checked, children, __children } = item
    handChanging.value = true
    emit('checkChange', true)
    if (checked) {
      item.checked = true
      item.indeterminate = false
    }
    if (children?.length || __children?.length)
      deepMap(children || __children, checked)

    deepMapParent(item, checked)
  }

  return {
    handChangeCheck,
    deepMapParent,
    deepSetList,
    handChanging
  }
}
